<?php

namespace app\command\tasks;

use app\common\repositories\energy\EnergyPlanRepository;
use app\common\repositories\room\RoomBasicRepository;
use app\helper\Log;
use think\facade\Db;
use app\common\repositories\bill\BillBasicRepository;
use app\common\repositories\bill\BillCatalogRepository;
use app\common\repositories\energy\EnergyBillRepository;
use app\common\repositories\contract\ContractBasicRepository;
use app\common\repositories\energy\EnergySharedRoomRepository;

/**
 * 每月生成账单
 * Class GenerateBillTask
 *
 * @package app\command\task
 */
class monthBillTask
{

    protected function writeLog($str)
    {
        Log::writeLog('检测租赁生成账单', $str, false);
    }

    /**
     * 执行任务
     * @return mixed
     */
    public function execute()
    {
        /** @var ContractBasicRepository $contractBasicRepository */
        $contractBasicRepository = app()->make(ContractBasicRepository::class);

        /** @var BillBasicRepository $billRepository */
        $billRepository = app()->make(BillBasicRepository::class);

        /** @var BillCatalogRepository $billCatalogRepository */
        $billCatalogRepository = app()->make(BillCatalogRepository::class);

        /** @var EnergyBillRepository $enertrBillRepository */
        $enertrBillRepository = app()->make(EnergyBillRepository::class);

        $day = (int)date('d');
        $this->writeLog('开始检测');
        try {
            Db::transaction(function () use ($contractBasicRepository, $day, $billRepository, $enertrBillRepository, $billCatalogRepository) {
                $contractBasicRepository->search([])
                    ->where('status', 'in', [2, 6])
                    ->where('bill_add_day', $day)
                    ->chunk(500, function ($list) use ($billRepository, $enertrBillRepository, $billCatalogRepository) {
                        foreach ($list as $k => $contractInfo) {
                            $rentStatus = 1; # 待审核账单
                            if ($contractInfo['sign_audit'] == 1) {
                                $rentStatus = 2; # 自动审核
                            }
                            $billData = [
                                'is_type' => 1,
                                'bill_type' => 1,
                                'status' => $rentStatus,
                                'month_time' => date('Y-m'),
                                'create_date' => date("Y-m-d"),
                                'contract_id' => $contractInfo['id'],
                                'user_id' => $contractInfo['user_id'],
                                'room_id' => $contractInfo['room_id'],
                                'items_id' => $contractInfo['items_id'],
                                'property_id' => $contractInfo['property_id'],
                                'overdue_fine_fee' => (float)$contractInfo['overdue_fine'],
                                'number' => $billRepository->generateBillNumber($contractInfo['property_id']),
                                'cutoff_date' => date("Y-m-d", strtotime("+{$contractInfo['bill_pay_day']} day")),
                            ];
                            $rentBillInfo = $billRepository->create($billData);
                            $billInfo['id'] = $rentBillInfo['id'];
                            $billInfo['status'] = $rentBillInfo['status'];
                            $billInfo['month_time'] = $rentBillInfo['month_time'];
                            $billInfo['property_id'] = $rentBillInfo['property_id'];
                            $billInfo['contract_id'] = $rentBillInfo['contract_id'];
                            # 生成租金及其它费用
                            $billCatalogRepository->taskContractOtherFee($contractInfo, $rentBillInfo);
                            # 生成能源费用
                            $enertrBillRepository->taskContractEnertrFee($contractInfo, $billInfo);
                            # 生成公摊费用
                            $enertrBillRepository->taskSharedExpenses($contractInfo, $billInfo);
                            $this->writeLog("租赁ID: " . $contractInfo['id'] . ', 账单生成成功 id: ' . $rentBillInfo['id']);
                        }
                    });
            });
            $this->writeLog('检测成功');
            return true;
        } catch (\Exception $e) {
            Log::exceptionWrite('租赁生成账单失败', $e);
            $this->writeLog('检测失败');
            return false;
        }
    }

}
